package com.xingda.packing.dmds.domain;

import com.xingda.packing.dmds.common.StorageUtils;
import com.xingda.packing.dmds.enums.*;
import com.xingda.packing.dmds.events.EventCreater;
import com.xingda.packing.dmds.minitor.entity.PkVisualSense;
import com.xingda.packing.dmds.minitor.mapper.PkVisualSenseMapper;
import com.xingda.packing.dmds.minitor.service.IPkAlarmHistoryService;
import com.xingda.packing.dmds.plc.service.PlcDirectiveService;
import com.xingda.packing.dmds.service.TaskManagerService3;
import com.xingda.packing.dmds.service.TaskManagerService4;
import com.xingda.packing.dmds.shunt.ticket.ShuntTicket;
import com.xingda.packing.dmds.task.ticket.AbstractTaskTicket;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Component("shuntProductionDMDSLine")
@Slf4j
public class ShuntProductionLine {
    @Resource
    @Getter
    IPkAlarmHistoryService pkAlarmHistoryService;
    @Resource
    @Getter
    EventCreater eventCreater;
    @Resource
    @Getter
    private ShuntArea shuntArea;
    @Resource
    private StorageUtils storageUtils;
    @Resource
    private TaskManagerService3 taskManagerService3;
    @Resource
    private TaskManagerService4 taskManagerService4;
    @Getter
    @Setter
    private boolean initRunning1 = false;
    @Getter
    @Setter
    private boolean initRunning2 = false;
    @Setter
    @Getter
    private AbstractTaskTicket taskTicket1;
    @Setter
    @Getter
    private AbstractTaskTicket taskTicket2;
    @Resource
    private PlcDirectiveService plcDirectiveService;
    @Resource
    @Getter
    private PackProductionLine packProductionLine;
    @Resource
    private PkVisualSenseMapper pkVisualSenseMapper;
    @Getter
    @Setter
    private int codeErrorNum1 = 0;
    @Getter
    @Setter
    private int snapErrorNum1 = 0;
    @Getter
    @Setter
    private int codeErrorNum2 = 0;
    @Getter
    @Setter
    private int snapErrorNum2 = 0;

    public void setCodeErrorNum(int area, int count) {
        if (area == 3) {
            setCodeErrorNum1(count);
        } else {
            setCodeErrorNum2(count);
        }

    }

    public void setSnapErrorNum(int area, int count) {
        if (area == 3) {
            setSnapErrorNum1(count);
        } else {
            setSnapErrorNum2(count);
        }
    }

    public int getCodeErrorNum(int area) {
        if (area == 3) {
            return getCodeErrorNum1();
        } else {
            return getCodeErrorNum2();
        }
    }

    public int getSnapErrorNum(int area) {
        if (area == 3) {
            return getSnapErrorNum1();
        } else {
            return getSnapErrorNum2();
        }
    }

    public AbstractTaskTicket getTaskTicketByArea(int area) {
        if (area == 3) {
            return taskTicket1;
        } else {
            return taskTicket2;
        }
    }

    public void setTaskTicketByArea(int area, AbstractTaskTicket taskTicket) {
        if (area == 3) {
            this.taskTicket1 = taskTicket;
        } else {
            this.taskTicket2 = taskTicket;
        }
    }

    public boolean initRunning(int area) {
        if (area == 3) {
            return initRunning1;
        } else {
            return initRunning2;
        }
    }

    public void setInitRunning(int area, boolean value) {
        if (area == 3) {
            initRunning1 = value;
        } else {
            initRunning2 = value;
        }
    }

    /**
     * 初始化
     */
    public void initStatus(int area) {
        AbstractTaskTicket ticket = storageUtils.loadTaskTicket(area);
        setTaskTicketByArea(area, ticket);
    }

    /**
     * 开启
     */
    public void start(int area) {
        if (area == 3) {
            CompletableFuture.runAsync(taskManagerService3);
        } else {
            CompletableFuture.runAsync(taskManagerService4);
        }
    }

    /**
     * 是否可以下发任务
     */
    public boolean checkCanAssignTaskTicket(int area) {
        AbstractTaskTicket taskTicket = getTaskTicketByArea(area);
        return taskTicket == null || taskTicket.getState() == TaskState.FINISH;
    }

    public void assignTaskTicket(AbstractTaskTicket taskTicket, int area) {
        if (checkCanAssignTaskTicket(area)) {
            setTaskTicketByArea(area, taskTicket);
            log.info("分流区任务单下发成功：任务单类型：{}", taskTicket.getType().getTypeName());
        }
    }

    public boolean isScanSignal(int area) {
        return plcDirectiveService.isShuntAreaSignal(area);
    }

    public boolean isSnapSignal(int area) {
        return plcDirectiveService.isSnapSignal(area);
    }

    /**
     * 获得分流区条形码
     */
    public String getScanWheelNo(int area) {
        return plcDirectiveService.getShuntAreaScanWheelNo(area);
    }

    public void wheelToLeftOrRight(int location, String code,int area) {
        plcDirectiveService.writeValueToShuntArea(location, code,area);
    }

    public boolean isShuntOver(int area) {
        return plcDirectiveService.isShuntOver(area);
    }

    public void restartShuntAreaSignal(int area) {
        plcDirectiveService.restartShuntAreaSignal(area);
    }

    public List<ProductBoxLocation> getAllProductBoxLocation() {
        List<ProductBoxLocation> list = new ArrayList<>();
        List<ProductBoxLocation> locationList1 = packProductionLine.getProductArea().locationList1;
        List<ProductBoxLocation> locationList2 = packProductionLine.getProductArea().locationList2;
        list.addAll(locationList1);
        list.addAll(locationList2);
        return list;
    }

    public boolean canShut(int location, int area) {
        if (location == 3) {
            return shuntArea.canPutToSql(1, area);
        } else {
            return shuntArea.canPutToSql(2, area);
        }
    }

    public void handleShuntEvent(int area, ShuntTicket shuntTicket) {
        setSnapErrorNum(area, 0);
        setCodeErrorNum(area, 0);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_CODE_ERROR_MORE_THAN_THREE, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_SNAP_ERROR_MORE_THAN_THREE, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.PRODUCT_TYPE_ERROR, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.NO_PRODUCT_TYPE, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_AVAILABLE, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_SHUNT, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ALREADY_PACKING, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_99, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_999, false, area);
        eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_9999, false, area);
        eventCreater.createPkEvent(EventType.SHUNT, area, WorkAreaType.getByID(area).getTypeName() + ":颜色:" + WheelSurfaceType.getByAB(shuntTicket.getWheel().getAb()).getGr());
        eventCreater.createPkEvent(EventType.SHUNT, area, WorkAreaType.getByID(area).getTypeName() + ":读码完成:", shuntTicket.getWheel().getBarCode(), "，<br>扭转值：", shuntTicket.getWheel().getTorsionValue().setScale(2, RoundingMode.HALF_UP).doubleValue(), "，<br>焊点数：", shuntTicket.getWheel().getSolderJointCount(), "，<br>是否重卷：", shuntTicket.getWheel().isAnew(), "，<br>产品类别：", shuntTicket.getWheel().getVFree2(), "，<br>客户：", shuntTicket.getWheel().getConsumerName());
        eventCreater.createPkEvent(EventType.SHUNT, area, WorkAreaType.getByID(area).getTypeName() + ":分流方向:" + ShuntAreaType.getByLocation(shuntTicket.getLocation()).getTypeName());
        storageUtils.saveTaskTicket(shuntTicket, area);
        packProductionLine.getRobot().setTagValue(area,false);
    }

    public int getProductType(int area) {
        return plcDirectiveService.getProductTypeToShunt(area);
    }

    public void createNoProductTypeEvent(int area) {
        eventCreater.createTriggerAlarm(AlarmTriggerType.NO_PRODUCT_TYPE, true, area);
        eventCreater.createPkEvent(EventType.SHUNT, area, WorkAreaType.getByID(area).getTypeName() + ":<br>从PLC未读取到工字轮类型,已停止分流区任务");
        stopTask(area);
    }

    public void saveTicket(ShuntTicket shuntTicket, int area) {
        setTaskTicketByArea(area, shuntTicket);
        storageUtils.saveTaskTicket(shuntTicket, area);
    }


    public void createAlarmEvent(String content, int tag) {
        eventCreater.createPkEvent(EventType.SHUNT, tag, WorkAreaType.getByID(tag).getTypeName() + ":" + content);
    }

    public void createShuntEvent(ShuntTicket shuntTicket, int area) {
        storageUtils.saveTaskTicket(shuntTicket, area);
        eventCreater.createPkEvent(EventType.SHUNT, area, WorkAreaType.getByID(area).getTypeName() + ":<br>创建任务成功,工字轮高度:" + WheelHeight.getByID(shuntTicket.getProductType()).getTypeName());
    }

    public void listenerShuntEvent(ShuntTicket taskTicket, int area) {
        storageUtils.saveTaskTicket(taskTicket, area);
        eventCreater.createPkEvent(EventType.SHUNT, area, WorkAreaType.getByID(area).getTypeName() + ":<br>分流完成,分流方向:", ShuntAreaType.getByLocation(taskTicket.getLocation()).getTypeName());
    }

    public void saveVisualSense(String scanWheelNo, int area) {
        PkVisualSense pkVisualSense = new PkVisualSense();
        pkVisualSense.setArea(area);
        if (scanWheelNo == null) {
            scanWheelNo = "#";
        }
        pkVisualSense.setScanWheelNo(scanWheelNo);
        pkVisualSense.setCreateTime(new Date());
        pkVisualSenseMapper.insert(pkVisualSense);
    }


    public void codeParsingSucceeded(int area) {
        plcDirectiveService.codeParsingSucceeded(area);
    }

    public void codeParsingFailed(int area) {
        plcDirectiveService.codeParsingFailed(area);
    }

    public void snapParsingSucceeded(int area) {
        plcDirectiveService.snapParsingSucceeded(area);
    }

    public void snapParsingFailed(int area) {
        plcDirectiveService.snapParsingFailed(area);
    }

    public void stopTask(int area) {
        ShuntTicket shuntTicket = new ShuntTicket();
        shuntTicket.setState(TaskState.FINISH);
        setTaskTicketByArea(area, shuntTicket);
        saveTicket(shuntTicket, area);
        setInitRunning(area, false);
    }
}
